﻿/*
 * nt_pb_ui_preview_wnd.cs
 * nt_pb_ui_preview_wnd
 * 
 * Github: https://github.com/daniulive/SmarterStreaming
 * 
 * Created by DaniuLive on 2017/05/12.
 * Copyright © 2014~2017 DaniuLive. All rights reserved.
 */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing.Drawing2D;

namespace VideoPro
{
    public struct NT_VideoFrame
    {
        public Int32 width_;   // 图像宽
        public Int32 height_;  // 图像高
        public IntPtr plane_;
        public Int32 stride_;
    }

    public partial class GdiPlay : Form
    {
        private NT_VideoFrame cur_video_frame_ = new NT_VideoFrame();

        public GdiPlay()
        {
            InitializeComponent();

            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.  
            SetStyle(ControlStyles.DoubleBuffer, true);         // 双缓冲  
        }

        public void OnRGBXImage(NT_VideoFrame frame)
        {
            cur_video_frame_ = frame;

            this.Invalidate();
        }

        private void CalScaleSize(int limit_w, int limit_h, int video_w, int video_h, ref double w, ref double h)
        {
	        w = limit_w;
	        h = limit_h;

            if (limit_h == 0 || video_w == 0 || video_h == 0)
            {
                return;
            }

	        if (video_w < 1)
		        return;

	        if (video_h < 1)
		        return;

	        double limit_ratio = limit_w*1.0 / limit_h;
            double video_ratio = video_w * 1.0 / video_h;

            double diff_ratio = Math.Abs(limit_ratio - video_ratio);
	        if (diff_ratio < 0.119)
	        {
		        //  比例差距很小的话，就直接缩放
		        w = limit_w;
		        h = limit_h;
	        }
	        else
	        {
		        if (video_ratio >= limit_ratio)
		        {
			        // 按宽缩放
			        w = limit_w;
			        h = w * video_h*1.0 / video_w;
		        }
		        else
		        {
			        // 按高缩放
			        h = limit_h;
			        w = h * video_w*1.0 / video_h;
		        }
	        }

	        if (w > limit_w)
		        w = limit_w;

	        if (h > limit_h)
		        h = limit_h;
        }


        private void nt_pb_ui_preview_wnd_Paint(object sender, PaintEventArgs e)
        {
            if (cur_video_frame_.plane_ == IntPtr.Zero)
            {
                return;
            }

            Bitmap bitmap = new Bitmap(cur_video_frame_.width_, cur_video_frame_.height_, cur_video_frame_.stride_,
                 System.Drawing.Imaging.PixelFormat.Format32bppRgb, cur_video_frame_.plane_);

            int image_width = cur_video_frame_.width_;
            int image_height = cur_video_frame_.height_;

            Graphics g = e.Graphics;//获取窗体画布
            g.SmoothingMode = SmoothingMode.HighSpeed;

            int limit_w = this.Width - 8;
            int limit_h = this.Height - 8;

            double d_w = 0, d_h = 0;

            if (image_width <= limit_w & image_height <= limit_h)
            {
                d_w = image_width;
                d_h = image_height;
            }
            else
            {
                CalScaleSize(limit_w, limit_h, image_width, image_height, ref d_w, ref d_h);
            }

            if (d_w > 0 && d_h > 0)
            {
                int d_x = (int)(this.Width / 2 - d_w / 2);
                int d_y = (int)(this.Height / 2 - d_h / 2);

                g.DrawImage(bitmap, d_x, d_y, (int)d_w, (int)d_h); //在窗体的画布中绘画出内存中的图像
            }
        }

        private void nt_pb_ui_preview_wnd_Load(object sender, EventArgs e)
        {

        }
    }
}
